<?php
/**
 *      [迷你云] (C)2009-2012 南京恒为网络科技.
 *   软件仅供研究与学习使用，如需商用，请访问www.miniyun.cn获得授权
 * 
 */
?>
<?php

class MFileGetController extends MApplicationComponent implements MIController {
    
    public function invoke($uri = null) {
                                parent::init ();
                                $url_manager = new MUrlManager ();
        $path = $url_manager->parsePathFromUrl ( $uri );
        $root = $url_manager->parseRootFromUrl ( $uri );
        if ($path == false || $root == false) {
            throw new MFilesException ( FXP::t ( MConst::PATH_ERROR ), MConst::HTTP_CODE_411 );
        }
                        $user = MUserManager::getInstance ()->getCurrentUser ();
        $device = MUserManager::getInstance ()->getCurrentDevice ();
        $user_id = $user->user_id;
        $user_nick = $user->user_name;
        $user_device_id = $device->device_id;
                                $rev = 0;
        if (isset ( $_REQUEST ["rev"] )) {
            $rev = ( int ) $_REQUEST ["rev"];
            if ($rev == 0) {                 throw new MFilesException ( FXP::t ( "The revision dosen't exist." ), MConst::HTTP_CODE_404 );
            }
        }
                                $path = "/" . $path;
        $path = "/" . $user_id . MUtils::convertStandardPath ( $path );
        $file_detail = MFiles::queryFilesByPath ( $path );
        if ($file_detail === false || count ( $file_detail ) == 0) {
            throw new MFilesException ( FXP::t ( MConst::NOT_FOUND ), MConst::HTTP_CODE_404 );
        }
        $file_detail = MFiles::exchange2Object ( $file_detail );
        
        $rev = isset($_REQUEST ["rev"]) ? $rev : $file_detail->version_id;
        
        $file_meta = MFileMetas::queryFileMeta ( $file_detail->file_path, MConst::VERSION );
        if ($file_meta == false || empty ( $file_meta )) {
            throw new MFilesException ( FXP::t ( MConst::INTERNAL_SERVER_ERROR ), MConst::HTTP_CODE_500 );
        }
                                if (MUtils::isExistReversion ( $rev, $file_meta [0] ["meta_value"] ) == false) {
            throw new MFilesException ( FXP::t ( "The revision dosen't exist." ), MConst::HTTP_CODE_404 );
        }
        $file_name = $file_detail->file_name;
        $file_id = $file_detail->id;
                                $version_id = $file_detail->version_id;
        if ($rev != 0) {
            $version_id = $rev;
        }
        $file_version = MFileVersions::queryFileVersionByID ( $version_id );
        if ($file_version === false) {
            throw new MFilesException ( FXP::t ( MConst::NOT_FOUND ), MConst::HTTP_CODE_404 );
        }
        
                                $signature = $file_version [0] ["file_signature"];
        $content_type = $file_version [0] ["mime_type"];
        $content_type = empty ( $content_type ) ? MConst::DEFAULT_DOWNLOAD_MIME_TYPE : $content_type;
        $file_path = DOCUMENT_ROOT_BLOCK . MUtils::getPathBySplitStr ( $signature );
        if (file_exists ( $file_path ) === false) {
            throw new MFilesException ( FXP::t ( MConst::NOT_FOUND ), MConst::HTTP_CODE_404 );
        }
                                if (headers_sent ()) {
            exit ();
        }
        $this->download_range ( $file_path, $file_name, $content_type );
    }
    
    private function download_range($file_path, $file_name, $ctype) {
        $size = filesize ( $file_path );
                Header ( "Content-type: $ctype" );
        Header ( "Cache-Control: public" );
        Header ( "Content-length: " . $size );
        $encoded_filename = urlencode ( $file_name );
        $encoded_filename = str_replace ( "+", "%20", $encoded_filename );
        $ua = isset($_SERVER ["HTTP_USER_AGENT"]) ? $_SERVER ["HTTP_USER_AGENT"] : NULL;
                if (preg_match ( "/MSIE/", $ua )) {
            header ( 'Content-Disposition: attachment; filename="' . $encoded_filename . '"' );
        } elseif (preg_match ( "/Firefox\/8.0/", $ua )){
            header ( 'Content-Disposition: attachment; filename="' . $file_name . '"' );
        } else if (preg_match ( "/Firefox/", $ua )) {
            header ( 'Content-Disposition: attachment; filename*="utf8\'\'' . $file_name . '"' );
        } else {
            header ( 'Content-Disposition: attachment; filename="' . $file_name . '"' );
        }
        $fp = fopen ( $file_path, "rb" );         if (isset ( $_SERVER ['HTTP_RANGE'] ) && ($_SERVER ['HTTP_RANGE'] != "") && preg_match ( "/^bytes=([0-9]+)-/i", $_SERVER ['HTTP_RANGE'], $match ) && ($match [1] < $size)) {
            $range = $match [1];
            fseek ( $fp, $range );
            header ( "HTTP/1.1 206 Partial Content" );
            header ( "Last-Modified: " . gmdate ( "D, d M Y H:i:s", filemtime ( $file_path ) ) . " GMT" );
            header ( "Accept-Ranges: bytes" );
            $rangesize = ($size - $range) > 0 ? ($size - $range) : 0;
            header ( "Content-Length:" . $rangesize );
            header ( "Content-Range: bytes " . $range . '-' . ($size - 1) . "/" . $size );
        } else {
            header ( "Content-Length: $size" );
            header ( "Accept-Ranges: bytes" );
            $range = 0;
            header ( "Content-Range: bytes " . $range . '-' . ($size - 1) . "/" . $size );
        }
                while ( ! feof ( $fp ) ) {
                        set_time_limit ( 0 );
            print (fread ( $fp, 1024 * 8 )) ;             flush ();             ob_flush ();
        }
        fclose ( $fp );
        exit ();
    }
    
    public function download_normal($file_path, $file_name, $ctype) {
        $encoded_filename = urlencode ( $file_name );
        $encoded_filename = str_replace ( "+", "%20", $encoded_filename );
        $ua = isset($_SERVER ["HTTP_USER_AGENT"]) ? $_SERVER ["HTTP_USER_AGENT"] : NULL;
        header ( "Cache-Control:" );
        header ( "Cache-Control: public" );
        header ( "Content-Type: " . $ctype );
                                if (preg_match ( "/MSIE/", $ua )) {
            header ( 'Content-Disposition: attachment; filename="' . $encoded_filename . '"' );
        } elseif (preg_match ( "/Firefox\/8.0/", $ua )){
            header ( 'Content-Disposition: attachment; filename="' . $file_name . '"' );
        } elseif (preg_match ( "/Firefox/", $ua )) {
            header ( 'Content-Disposition: attachment; filename*="utf8\'\'' . $file_name . '"' );
        } else {
            header ( 'Content-Disposition: attachment; filename="' . $file_name . '"' );
        }
        header ( "Accept-Ranges: none" );
        header ( "Content-Length: " . filesize ( $file_path ) );
                $fp = fopen ( "$file_path", "rb" );
                while ( ! feof ( $fp ) ) {
                        set_time_limit ( 0 );
            print (fread ( $fp, 1024 * 8 )) ;             flush ();             ob_flush ();
        }
        fclose ( $fp );
        exit ();
    }
    
    public function handleException($exception) {
        header ( "HTTP/1.1 " . $exception->getCode () . " " . $exception->getMessage () );
        echo $exception->getCode () . " " . $exception->getMessage ();
        return;
    
         }
}
?>